/**
 * @file feature_extractor.h
 * @brief 音频特征提取模块头文件
 */

#ifndef FEATURE_EXTRACTOR_H
#define FEATURE_EXTRACTOR_H

#include "webrtc_vad.h"

// 特征集合结构体
typedef struct {
    // VAD值
    float vad_value;
    
    // 音高特征
    float pitch;
    
    // 能量特征
    float energy;
    
    // 频谱特征
    float spectrum[256];
    float* spectrum_fft;  // 分贝幅度谱
    float* spectrum_mag;  // 线性幅度谱（新增，用于能量/亮度计算）
    
    // 音色特征
    float timbre_features;
    
    // 明亮度特征
    float brightness;
    
    // FFT处理必要的临时缓冲区
    float* window_buffer;        // 汉宁窗缓冲区(必须保留)
    float* fft_data;             // FFT数据（实部虚部交替存储，必须保留）
    
    // 预计算的对数重采样索引及临时缓冲区
    float* log_indices;         // 对数重采样索引（长度 = num_freq_bins）
    float* log_resampled_full;  // 全长对数重采样结果缓冲区（长度 = num_freq_bins）
    
    int num_freq_bins;          // 线性频谱截取后的bin数量
    int min_bin;               // 起始bin索引，便于快速访问
    
    // 处理参数
    int max_frame_size;          // 最大帧大小，用于内存分配
    int sample_rate;             // 音频采样率，从引擎获取
    
    // WebRTC VAD 相关
    VadInst* vad_inst;           // WebRTC VAD 实例
    int vad_sr;                  // 实例当前采样率（用于动态切换）
    
    // VAD 方法：0=WebRTC, 1=能量阈值
    int vad_method;
    float vad_energy_th;         // 能量阈值(归一化 RMS)

    // WebRTC VAD 转换用 PCM 缓冲
    int16_t* vad_pcm_buf;        // 长度固定(2048)即可覆盖 30ms@48k
    int      vad_pcm_size;

    /* --------- YIN Pitch 用静态缓冲区 (避免每帧 malloc) --------- */
    float* yin_diff;   /* 长度 >= max_frame_size+1 */
    float* yin_cmnd;   /* 同上 */
    float* yin_tmp;    /* 复用的 FFT/IFFT 临时缓冲, 长度 >= max_frame_size*2 */
} FeatureSet;

/**
 * @brief 创建特征集合
 * 
 * @param max_frame_size 最大帧大小，用于内存分配
 * @param sample_rate 音频采样率
 * @return FeatureSet* 特征集合指针，失败返回NULL
 */
FeatureSet* create_feature_set(int max_frame_size, int sample_rate);

/**
 * @brief 释放特征集合
 * 
 * @param features 特征集合指针
 */
void free_feature_set(FeatureSet* features);

/**
 * @brief VAD检测函数
 * 
 * @param preprocessed_audio 预处理后的音频数据
 * @param length 音频数据长度
 * @param features 输出的特征集合
 * @return int 成功返回0，失败返回错误码
 */
int detect_vad(const float* preprocessed_audio, int length, FeatureSet* features);

/**
 * @brief 提取音高特征
 * 
 * @param preprocessed_audio 预处理后的音频数据
 * @param length 音频数据长度
 * @param features 输出的特征集合
 * @return int 成功返回0，失败返回错误码
 */
int extract_pitch_feature(const float* preprocessed_audio, int length, FeatureSet* features);

/**
 * @brief 提取能量特征
 * 
 * @param preprocessed_audio 预处理后的音频数据
 * @param length 音频数据长度
 * @param features 输出的特征集合
 * @return int 成功返回0，失败返回错误码
 */
int extract_energy_feature(const float* preprocessed_audio, int length, FeatureSet* features);

/**
 * @brief 提取频谱特征
 * 
 * @param preprocessed_audio 预处理后的音频数据
 * @param length 音频数据长度
 * @param features 输出的特征集合
 * @return int 成功返回0，失败返回错误码
 */
int extract_spectrum_feature(const float* preprocessed_audio, int length, FeatureSet* features);

/**
 * @brief 提取音色特征
 * 
 * @param preprocessed_audio 预处理后的音频数据
 * @param length 音频数据长度
 * @param features 输出的特征集合
 * @return int 成功返回0，失败返回错误码
 */
int extract_timbre_feature(const float* preprocessed_audio, int length, FeatureSet* features);

/**
 * @brief 提取明亮度特征
 * 
 * @param preprocessed_audio 预处理后的音频数据
 * @param length 音频数据长度
 * @param features 输出的特征集合
 * @return int 成功返回0，失败返回错误码
 */
int extract_brightness_feature(const float* preprocessed_audio, int length, FeatureSet* features);

/**
 * @brief 提取所有特征
 * 
 * @param preprocessed_audio 预处理后的音频数据
 * @param length 音频数据长度
 * @param features 输出的特征集合
 * @return int 成功返回0，失败返回错误码
 */
int extract_features(const float* preprocessed_audio, int length, FeatureSet* features);

#endif /* FEATURE_EXTRACTOR_H */ 